/**
 * 2024.05.18 17:18 星期六 晴  相安无事 只是昨日 又想到 还有 一关 我不太想过了 想脱口而出 但好像 我最后还是没说 只想让他 当狗 不然太便宜他了
 * 这个
 * *解析 元素
 * *创建 元素
 * *记录 元素
 * 装配函数 触发特定 自装配函数
 */

import {
  ObjectOnlyPushSet,
  toStringTypeCheck,
} from '../../components/aaanewApp/global/global';
import { avandaTaskObj } from '../avanda/avandaUnitObj/avandaUnitObj';

const splitStr = '_';

const midSplitStr = '-';

const avapre = 'ava';

/**
 * 返回元素 的 avanda 对象 关键字
 */
// const avaO = `ava_obj`;

const avaL = `ava_listened`;

const avaDescribepre = 'avanda listened element';

const groupto = 'groupto';

const data = 'data';

const target = 'target';

const attribute = 'attribute';

const EnumInfo = 'enumInfo';

let defaultAttributeInfo = { data: [avaL] };

let defaultEnumInfo = { data: [], attribute: { data: [] }, groupto: avaL };

/**
 * 将 定义的 信息 挂载 到 元素上
 * @param {element} element doc.element 挂载元素
 * @param {Object} enumInfo 挂载信息 默认信息值 let defaultEnumInfo
 */
function EnumElement(element, enumInfo = defaultEnumInfo) {
  let returnInfo;

  returnInfo = emitElementInfo(element, enumInfo);

  return returnInfo;
}

function emitElementInfo(el, enumInfo) {
  let handler = { set: setH };

  let returnInfo;
  // 元素 avanda obj 名称
  let elavaName = `${avapre}${splitStr}${el.id}`;
  // 元素 avanda obj 描述
  let elavaDescribe = `${avaDescribepre} ${midSplitStr} ${el.id}`;

  // 元素 自定义 信息
  addAttributeInfos(el, enumInfo[attribute]);
  // 默认 信息
  addAttributeInfos(el, defaultAttributeInfo);

  //   监听 set attribute 直接挂载到 元素上
  proxyEnumAttributeInfo();

  returnInfo = new avandaTaskObj({
    taskName: elavaName,
    describe: elavaDescribe,
    groupto: enumInfo[groupto],
  });

  //   向 avanda 添加 挂载信息
  returnInfo[EnumInfo] = enumInfo;

  //   向 avanda 添加 target 元素指定
  returnInfo[target] = el;

  /**
   * 代理 挂载 对象 的 attribute 信息项
   *
   * 1.改动 avanda 上的 attribute 内信息
   *
   * 2.挂载 到元素上
   */
  function proxyEnumAttributeInfo() {
    enumInfo[attribute] = new Proxy(enumInfo[attribute], handler);
  }

  function setH(that, key, val) {
    if (key == data) {
      return true;
    }
    if (!ObjectOnlyPushSet(that, key, val)) {
      that[key] = val;
    }
    el.setAttribute(key, val);
    return true;
  }

  return returnInfo;
}

/**
 *
 * @param {Element} el 元素
 * @param {Object|String} key 内置属性  信息 记录集 {data:[]}
 * @param {any} val 属性值
 */
function addAttributeInfos(el, key, val) {
  if (toStringTypeCheck(key, 'string')) {
    el.setAttribute(key, val);
  } else if (toStringTypeCheck(key, 'object')) {
    for (const k of key[data]) {
      addAttributeInfos(el, k, key[k]);
    }
  }
}

export { EnumElement };
